<!--
 * @description 轮播组件
 * @author: 陈陈
 * @date: 2025/05/09
 * @phone: 18560000860
 * @email: 18560000860@qq.com
 * @company: 济南晨霜信息技术有限公司 /
 * @business: 承接前后端项目的开发
-->
<template>
	<view
		class="pure-swiper"
		:class="_classes"
		:style="_styles"
	>
		<swiper
			class="pure-swiper__swiper"
			:active-class="activeClass"
			:changing-class="changingClass"
			:autoplay="autoplay"
			:current="current"
			:current-item-id="currentItemId"
			:interval="interval"
			:duration="duration"
			:circular="circular"
			:vertical="vertical"
			:previous-margin="previousMargin"
			:next-margin="nextMargin"
			:acceleration="acceleration"
			:disable-programmatic-animation="disableProgrammaticAnimation"
			:display-multiple-items="displayMultipleItems"
			:skip-hidden-item-layout="skipHiddenItemLayout"
			:disable-touch="disableTouch"
			:easing-function="easingFunction"
			@change="_handleChange"
			@transition="_handleTransition"
			@animationfinish="_handleAnimationFinish"
		>
			<swiper-item
				class="pure-swiper__item"
				:class="{
					'pure-swiper__item--active': _activeIndexes.includes(index),
					'pure-swiper__item--prev': _prevIndexes.includes(index),
					'pure-swiper__item--next': _nextIndexes.includes(index)
				}"
				v-for="(item, index) in list"
				:key="index"
				@tap="_handleItemClick(item, index)"
				:hover-class="hoverClass"
				:current="index"
			>
				<view class="pure-swiper__item__content">
					<slot
						:item="item"
						:index="index"
					>
						<view class="pure-swiper__item__image">
							<pure-image
								width="100%"
								height="100%"
								:src="item?.[srcKey] || item"
								:placeholder="item?.placeholder"
								:mode="item?.mode || mode"
								:lazy-load="item?.lazyLoad"
								:fade-show="item?.fadeShow"
								:webp="item?.webp"
								:showMenuByLongpress="item?.showMenuByLongpress"
								:draggable="item?.draggable"
							></pure-image>
						</view>
					</slot>
				</view>
			</swiper-item>
		</swiper>

		<!-- 指示器 -->
		<view
			class="pure-swiper__indicator"
			v-if="indicator || $slots.indicator"
		>
			<slot name="indicator">
				<pure-indicator
					v-bind="_props"
					:total="list?.length"
					:list="list"
					:mode="indicatorMode"
					@onClick="_handleIndicatorClick"
				></pure-indicator>
			</slot>
		</view>

		<!-- 切换器 -->
		<view
			class="pure-swiper__prev-next"
			v-if="progresor || $slots.progresor"
		>
			<slot name="progresor">
				<pure-progresor
					v-bind="progresorOpts"
					:disablePrev="_disablePrev"
					:disableNext="_disableNext"
					@onPrev="_handlePrev"
					@onNext="_handleNext"
				></pure-progresor>
			</slot>
		</view>
	</view>
</template>

<script>
	import commonComponentOptions from "../../config/options";
	export default {
		options: commonComponentOptions
	};
</script>

<script setup>
	import { computed } from "vue";
	import props from "./props";

	// -------------------------------------------------------------------------------- Props
	const _props = defineProps(props);

	// -------------------------------------------------------------------------------- Emits
	const _emits = defineEmits(["onChange", "onTransition", "onAnimationFinish", "onClick"]);

	// -------------------------------------------------------------------------------- Classes
	const _classes = computed(() => {
		const array = [];

		// 指示器是否显示在下方
		if (_props.indicatorOutside) array.push("pure-swiper--indicator-outside");

		// 指示器模式
		if (_props.indicatorMode) array.push(`pure-swiper--indicator-mode--${_props.indicatorMode}`);

		return array;
	});

	// -------------------------------------------------------------------------------- Styles
	const _styles = computed(() => {
		const array = [];

		// 宽
		if (_props.width) array.push(`--pure-swiper-width: ${_props.width};`);

		// 高
		if (_props.height) array.push(`--pure-swiper-height: ${_props.height};`);

		// 圆角大小
		if (_props.radius) array.push(`--pure-swiper-border-radius: ${_props.radius};`);

		// item 之间的间距
		if (_props.gap) array.push(`--pure-swiper-item-padding: 0 calc(${_props.gap} / 2);`);

		// 缩放比例
		if (_props.scale) {
			array.push(`--pure-swiper-item-prev-transform: scale(${_props.scale});`);
			array.push(`--pure-swiper-item-next-transform: scale(${_props.scale});`);
		}

		return array;
	});

	// 禁用上一个？
	const _disablePrev = computed(() => {
		if (_props?.circular) return false;
		return _props.current === 0;
	});

	// 禁用下一个？
	const _disableNext = computed(() => {
		if (_props?.circular) return false;
		return _props.current === _props.list.length - 1;
	});

	// 一屏显示项的下标
	const _activeIndexes = computed(() => {
		const indexes = [];

		// 一屏显示的数量
		const displayMultipleItems = Number(_props.displayMultipleItems || 1);

		for (let i = 0; i < displayMultipleItems; i++) {
			const idx = (_props.current + i) % _props.list.length;
			indexes.push(idx);
		}

		return indexes;
	});

	// 后置
	const _nextIndexes = computed(() => {
		const indexes = [];

		// 一屏显示的最后一个
		const lastIndex = _activeIndexes.value[_activeIndexes.value.length - 1];

		// 一屏显示的数量
		const displayMultipleItems = Number(_props.displayMultipleItems || 1);

		// 后置数量，向下取整
		const count = ~~((_props.list.length - displayMultipleItems) / 2);

		for (let i = 1; i <= count; i++) {
			const idx = (lastIndex + i) % _props.list.length;
			indexes.push(idx);
		}

		return indexes;
	});

	// 前置
	const _prevIndexes = computed(() => {
		const indexes = [];

		// 一屏显示的第一个
		const firstIndex = _activeIndexes.value[0];

		// 一屏显示的数量
		const displayMultipleItems = Number(_props.displayMultipleItems || 1);

		// 前置数量，向下取整
		const count = ~~((_props.list.length - displayMultipleItems) / 2);

		for (let i = 1; i <= count; i++) {
			const idx = Math.abs(firstIndex - i + _props.list.length) % _props.list.length;
			indexes.push(idx);
		}

		return indexes;
	});

	// 点击事件
	function _handleItemClick(item, index) {
		_emits("onClick", item, index);

		// 预览
		if (_props.preview) _preview(item, index);
	}

	// 预览资源
	function _preview(_, index) {
		uni.previewImage({
			current: index,
			urls: _props.list.map((item) => {
				return item?.[_props?.srcKey] || item;
			})
		});
	}

	// 指示器切换导致的变化事件
	function _handleIndicatorClick(index) {
		_emits("onChange", {
			detail: {
				current: index,
				source: "indicator"
			}
		});
	}

	// 上一个
	function _handlePrev() {
		let index = _props.current === 0 ? _props.list.length - 1 : _props.current - 1;
		_emits("onChange", {
			detail: {
				current: index,
				source: "progresor"
			}
		});
	}

	// 下一个
	function _handleNext() {
		let index = _props.current === _props.list.length - 1 ? 0 : _props.current + 1;
		_emits("onChange", {
			detail: {
				current: index,
				source: "progresor"
			}
		});
	}

	// 切换事件
	function _handleChange(event) {
		_emits("onChange", event);
	}

	// 过渡事件
	function _handleTransition(event) {
		_emits("onTransition", event);
	}

	// 动画结束事件
	function _handleAnimationFinish(event) {
		_emits("onAnimationFinish", event);
	}
</script>

<style scoped lang="scss">
	@import "./style.scss";
</style>
